//
//  TextAnimation.m
//  GiganticWhale
//
//  Created by GiganticWhale on 16/8/20.
//  Copyright © 2016年 Gigantic. All rights reserved.
//

#import "TextAnimation.h"
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
#import <objc/runtime.h>

static char animationFinishBlock;

#if defined(__IPHONE_10_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0)
@interface TextAnimation () <CAAnimationDelegate>
#else
@interface TextAnimation ()
#endif

@property (nonatomic,strong)CALayer *animationLayer;
@property (nonatomic,strong)CAShapeLayer *pathLayerE;
@property (nonatomic,strong)CAShapeLayer *pathLayerL;
@property (nonatomic,strong)CAShapeLayer *pathLayerV;
@property (nonatomic,strong)CAShapeLayer *pathLayerE2;

@end

@implementation TextAnimation

-(instancetype)initWithFrame:(CGRect)frame  title:(NSString *)title{
    self = [super initWithFrame:frame];
    if (self){
        self.size_height = [NSString contentofHeightWithFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:37]];
        [self createView];
        [self setupTextLayerWithTitle:title];
    }
    return self;
}

-(instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self){
        self.backgroundColor = UURandomColor;
        self.size_height = [NSString contentofHeightWithFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:37]];
        [self createView];
        
    }
    return self;
}

#pragma mark - createView
-(void)createView{
    self.animationLayer = [CALayer layer];
    self.animationLayer.frame = self.bounds;
//    self.animationLayer.backgroundColor = UURandomColor.CGColor;
    [self.layer addSublayer:self.animationLayer];
}

-(void)cleanPath{
    [self cleanPathWithLayer:self.pathLayerE];
    [self cleanPathWithLayer:self.pathLayerL];
    [self cleanPathWithLayer:self.pathLayerV];
    [self cleanPathWithLayer:self.pathLayerE2];
}

-(void)cleanPathWithLayer:(CAShapeLayer *)layer{
    if (layer){
        [layer removeFromSuperlayer];
        layer = nil;
    }
}

-(void)setupTextLayerWithTitle:(NSString *)title{
    //    [self cleanPath];
    
    CGMutablePathRef letters = CGPathCreateMutable();
    CTFontRef font = CTFontCreateWithName(CFSTR("HelveticaNeue-Bold"), 37.0f, NULL);
    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id _Nonnull)((CTFontRef)font), kCTFontAttributeName, nil];
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:title attributes:attrs];
    CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrString);
    CFArrayRef runArray = CTLineGetGlyphRuns(line);
    for (CFIndex runIndex = 0 ; runIndex < CFArrayGetCount(runArray);runIndex++){
        CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray, runIndex);
        CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
        for (CFIndex runGlyphIndex = 0; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++) {
            CFRange thisGlyphRange = CFRangeMake(runGlyphIndex, 1);
            CGGlyph glyph;
            CGPoint position;
            CTRunGetGlyphs(run, thisGlyphRange, &glyph);
            CTRunGetPositions(run, thisGlyphRange, &position);
            {
                CGMutablePathRef letters1 = CGPathCreateMutable();
                CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
                CGAffineTransform t = CGAffineTransformMakeTranslation(position.x, position.y);
                CGPathAddPath(letters1, &t, letter);
                CGPathAddPath(letters, &t, letter);
                
                UIBezierPath *path = [UIBezierPath bezierPath];
                [path moveToPoint:CGPointZero];
                [path appendPath:[UIBezierPath bezierPathWithCGPath:letters1]];
                
                [self autoPathWithPath:path andIndex:runGlyphIndex];
                
                CGPathRelease(letters1);
            }
        }
    }
    CFRelease(line);
    
    CGPathRelease(letters);
    CFRelease(font);
}


#pragma mark - setting Frame
-(void)autoPathWithPath:(UIBezierPath *)path andIndex:(NSInteger)index{
    CAShapeLayer *pathLayer = [CAShapeLayer layer];
//    pathLayer.backgroundColor = UURandomColor.CGColor;
    CGFloat fontHeight = [NSString contentofHeightWithFont:GFont];

    if (index == 0){                // E
        self.pathLayerE = pathLayer;
        CGSize contentOfSize = [@"炽" sizeWithCalcFont:GFont constrainedToSize:CGSizeMake(CGFLOAT_MAX, fontHeight)];
        CGSize contentOfSize1 = [@"炽" sizeWithCalcFont:GFont constrainedToSize:CGSizeMake(contentOfSize.width, CGFLOAT_MAX)];
        self.pathLayerE.frame = CGRectMake(0, 10, contentOfSize.width, contentOfSize1.height);
    } else if (index == 1){         // L
        self.pathLayerL = pathLayer;
        CGSize contentOfSize = [@"热" sizeWithCalcFont:GFont constrainedToSize:CGSizeMake(CGFLOAT_MAX, fontHeight)];
        CGSize contentOfSize1 = [@"热" sizeWithCalcFont:GFont constrainedToSize:CGSizeMake(contentOfSize.width, CGFLOAT_MAX)];
        self.pathLayerL.frame = CGRectMake(CGRectGetMaxX(self.pathLayerE.frame) + LCFloat(17), self.pathLayerE.frame.origin.y + 5, contentOfSize.width, contentOfSize1.height);
    } else if (index == 2){         // V
        self.pathLayerV = pathLayer;
        CGSize contentOfSize = [@"教" sizeWithCalcFont:GFont constrainedToSize:CGSizeMake(CGFLOAT_MAX, fontHeight)];
        self.pathLayerV.frame = CGRectMake(CGRectGetMaxX(self.pathLayerL.frame) + LCFloat(17), self.pathLayerE.frame.origin.y + 5, contentOfSize.width, fontHeight);
    } else if (index == 3){         // E
        self.pathLayerE2 = pathLayer;
        CGSize contentOfSize = [@"育" sizeWithCalcFont:GFont constrainedToSize:CGSizeMake(CGFLOAT_MAX, fontHeight)];
        self.pathLayerE2.frame = CGRectMake(CGRectGetMaxX(self.pathLayerV.frame) + LCFloat(17), self.pathLayerE.frame.origin.y + 5, contentOfSize.width, fontHeight);
    }
    
    pathLayer.bounds = CGPathGetBoundingBox(path.CGPath);
    pathLayer.geometryFlipped = YES;
    pathLayer.path = path.CGPath;
    pathLayer.strokeColor =    [[UIColor clearColor] CGColor];
    pathLayer.fillColor = nil;
    pathLayer.lineWidth = .5f;
    pathLayer.lineJoin = kCALineJoinBevel;
    
    self.size_width = CGRectGetMaxX(self.pathLayerE2.frame) + LCFloat(3);
    
    [self.animationLayer addSublayer:pathLayer];
}

#pragma mark - Show Animation
-(void)showAnimation{
    [self.pathLayerE removeAllAnimations];
    [self.pathLayerL removeAllAnimations];
    [self.pathLayerV removeAllAnimations];
    [self.pathLayerE2 removeAllAnimations];

    
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 0.5;
    pathAnimation.delegate = self;
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.5f];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    [pathAnimation setValue:@"0" forKey:@"anim1"];
    
    [self.pathLayerE addAnimation:pathAnimation forKey:@"ani1"];
}

#pragma mark - AniamtionDelegate
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    if ([[anim valueForKey:@"anim1"] isEqualToString:@"0"]){            // 【E】
        [self tempAnimationLayer:self.pathLayerE];
        [self showAnimation2WithIndex:0];
    } else if ([[anim valueForKey:@"anim2"] isEqualToString:@"0"]){
        [self showAnimationManager1WithIndex:1];
    } else if ([[anim valueForKey:@"anim1"] isEqualToString:@"1"]){     // 【L】
        [self tempAnimationLayer:self.pathLayerL];
        [self showAnimation2WithIndex:1];
    } else if ([[anim valueForKey:@"anim2"] isEqualToString:@"1"]){
        [self showAnimationManager1WithIndex:2];
    }else if ([[anim valueForKey:@"anim1"] isEqualToString:@"2"]){     // 【V】
        [self tempAnimationLayer:self.pathLayerV];
        [self showAnimation2WithIndex:2];
    } else if ([[anim valueForKey:@"anim2"] isEqualToString:@"2"]){
        [self showAnimationManager1WithIndex:3];
    }else if ([[anim valueForKey:@"anim1"] isEqualToString:@"3"]){      // 【E】
        [self tempAnimationLayer:self.pathLayerE2];
        [self showAnimation2WithIndex:3];
    } else if ([[anim valueForKey:@"anim2"] isEqualToString:@"3"]){
        // 结束
        void(^block)() = objc_getAssociatedObject(self, &animationFinishBlock);
        if (block){
            block();
        }
    }
}



#pragma mark - Animation 1
-(void)showAnimationManager1WithIndex:(NSInteger)index{
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 0.01f;
    pathAnimation.delegate = self;
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.5f];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    [pathAnimation setValue:[NSString stringWithFormat:@"%li",(long)index] forKey:@"anim1"];
    
    if (index == 0){
        [self.pathLayerE addAnimation:pathAnimation forKey:@"anim1"];
    } else if (index == 1){
        [self.pathLayerL addAnimation:pathAnimation forKey:@"anim1"];
    } else if (index == 2){
        [self.pathLayerV addAnimation:pathAnimation forKey:@"anim1"];
    } else if (index == 3){
        [self.pathLayerE2 addAnimation:pathAnimation forKey:@"anim1"];
    }
}

#pragma mark - 动画2
-(void)showAnimation2WithIndex:(NSInteger)index{
    // 【翻转】
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    animation.duration = .25f;                                              // 持续时间
    animation.repeatCount = 1;                                              // 重复次数
    animation.fromValue = [NSNumber numberWithFloat: M_PI];                 // 起始角度
    animation.toValue = [NSNumber numberWithFloat:2 * M_PI];                // 终止角度
    animation.delegate = self;
    NSInteger indexValue = index ;
    [animation setValue:[NSString stringWithFormat:@"%li",(long)indexValue] forKey:@"anim2"];
    
    // 【渐变】
    CABasicAnimation *animation2=[CABasicAnimation animationWithKeyPath:@"opacity"];
    animation2.fromValue=[NSNumber numberWithFloat:.0f];
    animation2.toValue=[NSNumber numberWithFloat:1.0f];
    animation2.duration = .3f;
    animation2.repeatCount = 1;
    animation2.removedOnCompletion = NO;
    animation2.fillMode = kCAFillModeForwards;
    
    // 【组合】
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.duration = .3f;
    group.repeatCount = 1;
    group.animations = [NSArray arrayWithObjects:animation, animation2, nil];
    group.delegate = self;
    [group setValue:[NSString stringWithFormat:@"%li",(long)indexValue] forKey:@"anim2"];
    
    if (indexValue == 0){
        [self.pathLayerE addAnimation:group forKey:@"anim2"];
    } else if (indexValue == 1){
        [self.pathLayerL addAnimation:group forKey:@"anim2"];
    } else if (indexValue == 2){
        [self.pathLayerV addAnimation:group forKey:@"anim2"];
    } else if (indexValue == 3){
        [self.pathLayerE2 addAnimation:group forKey:@"anim2"];
    }
}



#pragma mark - temp
-(void)tempAnimationLayer:(CAShapeLayer *)layer{
    layer.fillColor = [UIColor blackColor].CGColor;
    layer.strokeColor = [UIColor clearColor].CGColor;
}

-(void)showAnimationWithFinishBlock:(void(^)())finish{
    objc_setAssociatedObject(self, &animationFinishBlock, finish, OBJC_ASSOCIATION_COPY_NONATOMIC);
    [self showAnimation];
}
@end
